import { get_back_observable } from "@lib/alen-helper/base/fun";
import { EventClass } from "@lib/alen-helper/node/baseClass";
import { LibUniqueID } from "@lib/alen-helper/node/uniqueID";
import { Menu, MenuItemConstructorOptions, MenuItem } from "electron";

export namespace AppMenu {
    export interface MenuOptions {
        name: string,
        click: (() => AndAsyncObj<Empty>) | null,
        childrens: MenuOptions[],
    }

    export interface MenuItem {
        id: string,
        options: MenuOptions,
    }

    export type PartialMenuOptions = Partial<Omit<MenuOptions, 'childrens'>> & { childrens?: PartialMenuOptions[] | null }
}

export class AppMenu extends EventClass<{}> {

    _srcMenu: Menu;

    constructor(
        options: AppMenu.PartialMenuOptions[],
        BaseOptions?: Partial<EventClass.BaseOptions>
    ) {
        super('AppMenu', BaseOptions);
        this._srcMenu = this._buildMenu(options);
    }

    private _buildMenuOptions(options: AppMenu.PartialMenuOptions) {
        if (!options.name) throw this._err('参数出错', '没有名称');
        let op: AppMenu.MenuOptions = {
            name: '',
            click: null,
            childrens: [],
        };
        op = Object.assign(op, options) as AppMenu.MenuOptions;
        //===============
        if (op.childrens && op.childrens.length > 0) {
            for (let i = 0; i < op.childrens.length; i++) {
                op.childrens[i] = this._buildMenuOptions(op.childrens[i] as AppMenu.PartialMenuOptions)
            }
        } else {
            op.childrens = [];
        }
        return op;
    }

    private _buidMenuSrcOptions(options: AppMenu.MenuOptions) {
        const id = LibUniqueID.id16();
        let srcOptions: MenuItemConstructorOptions = {
            id,
            label: options.name,
            click: () => {
                if (!options.click) return;
                get_back_observable(options.click())
                    .subscribe({
                        complete: () => {

                        },
                        error: err => {
                            //
                        }
                    });
            }
        }
        //===============
        if (options.childrens.length > 0) {
            srcOptions.submenu = [];
            for (let o of options.childrens) {
                srcOptions.submenu.push(this._buidMenuSrcOptions(o));
            }
        }
        return srcOptions;
    }

    private _buidMenuSrcItem(options: AppMenu.PartialMenuOptions) {
        const op = this._buildMenuOptions(options);
        const srcOp = this._buidMenuSrcOptions(op);
        const item = new MenuItem(srcOp);
        return item;
    }

    private _buildMenu(options: AppMenu.PartialMenuOptions[]) {
        let items: MenuItem[] = [];
        for (let o of options) {
            items.push(this._buidMenuSrcItem(o));
        }
        return Menu.buildFromTemplate(items);
    }

    static setApplicationMenu(menu: AppMenu | AppMenu.PartialMenuOptions[]) {
        if (menu instanceof AppMenu) {
            Menu.setApplicationMenu(menu._srcMenu);
            return menu;
        } else {
            const appMenu = new AppMenu(menu);
            Menu.setApplicationMenu(appMenu._srcMenu);
            return appMenu;
        }
    }
}